#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include "serialTool.h"
#include "toysort.h"
#include "mypwm.h"
#include "wiringPi.h"
#include <pthread.h>
#include "myoled.h"
#include "mysocket.h"
#include <netinet/tcp.h>
//  #include<sys/types.h>

static bool flag = false;
int fd;
pthread_mutex_t key_1;
pthread_cond_t cond_1;
static bool judge_exist(char *mjpg)
{
  FILE *str;
  char tmp[128] = "\0";
  sprintf(tmp, "ps -aux | grep %s|grep -v grep", mjpg);
  if ((str = popen(tmp, "r")) != NULL)
  {
    memset(tmp, 0, sizeof(tmp));
    if (fgets(tmp, sizeof(tmp), str) != NULL)
    {
      if (strstr(tmp, "mjpg_streamer"))
      {
        flag = true;
        return flag;
      }
      else
      {
        return flag;
      }
    }
    return flag;
  }
  pclose(str);
}

void *ctloled(void *array)
{

  pthread_detach(pthread_self());
  myoled_init();
  oled_display(array);
  pthread_exit(0);
}

void *ctlsu(void *array)
{
  pthread_detach(pthread_self());
  unsigned char *buffer = (unsigned char *)array;

  if (buffer != NULL)
  {
    serialPuts(fd, buffer, 6);
  }
  pthread_exit(0);
}

void *ctlpwm(void *array)
{
  pthread_detach(pthread_self());
  unsigned char *buffer = (unsigned char *)array;
  if (buffer[2] == 0x61)
  {
    pwm_write(pwm_one);
    sleep(3);
    pwm_stop(pwm_one);
  }
  else if (buffer[2] == 0x62)
  {
    pwm_write(pwm_two);
    sleep(3);
    pwm_stop(pwm_two);
  }
  else if (buffer[2] == 0x63)
  {
    pwm_write(pwm_three);
    sleep(3);
    pwm_stop(pwm_three);
  }
  pthread_exit(0);
}

void *sucat()
{
  int len;
  unsigned char buffer[6] = {0xAA, 0X55, 0X00, 0X00, 0X55, 0XAA};
  while (1)
  {

    len = serialGets(fd, buffer);
    printf("buffer:%d", buffer[2]);
    if (len > 0 && (buffer[2] == 0x66))
    {
      buffer[2] == 0x00;
      pthread_mutex_lock(&key_1);
      pthread_cond_signal(&cond_1);
      pthread_mutex_unlock(&key_1);
    }
  }
  pthread_exit(0);
}

void *alycat()
{
  char *ty = NULL;
  unsigned char buffer[6] = {0xAA, 0X55, 0X00, 0X00, 0X55, 0XAA};
  pthread_t alySndMark;
  pthread_t pwmMark;
  pthread_t oledMark;

  while (1)
  {
    pthread_mutex_lock(&key_1);
    pthread_cond_wait(&cond_1, &key_1);
    pthread_mutex_unlock(&key_1);
    buffer[2] = 0x00;
    system(Wget_shot);
    if (0 == access(Get_image, F_OK))
    {
      ty = toysort_category(ty);

      if (strstr(ty, "益智类"))
        buffer[2] = 0x61;
      else if (strstr(ty, "娱乐类"))
        buffer[2] = 0x62;
      else if (strstr(ty, "运动类"))
        buffer[2] = 0x63;
      else
        buffer[2] = 0x65;
    }
    else
      buffer[2] = 0x65;
    pthread_create(&alySndMark, NULL, ctlsu, (void *)buffer);
    pthread_create(&pwmMark, NULL, ctlpwm, (void *)buffer);
    pthread_create(&oledMark, NULL, ctloled, (void *)buffer);

    remove(Get_image);
  }
  pthread_exit(0);
}

void *sockcat()
{
  int cli_fd;
  int server_fd;
  int cli_len;
  char buffer[6];
  int nread;
  struct sockaddr_in client;
  memset(&client, 0, sizeof(struct sockaddr_in));
  server_fd = socket_init();
  printf("%s|%s|%d:server_fd=%d\n", __FILE__, __func__, __LINE__, server_fd);
  if (-1 == server_fd)
  {
    pthread_exit(0);
  }
  sleep(3);
  while (1)
  {
    cli_len = sizeof(struct sockaddr_in);
    cli_fd = accept(server_fd, (struct sockaddr *)&client, &cli_len);
    int keep_alive = 1;
    int keep_idle = 5;
    int keep_interval = 3;
    int keep_count = 3;

    if(-1 == setsockopt(cli_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keep_alive, sizeof(keep_alive)))
    {
      perror("SO_KEEPALIVE error");
      break;
    }
    if(-1 == setsockopt(cli_fd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keep_idle, sizeof(keep_idle)))
    {
      perror("TCP_KEEPIDLE error");
      break;
    }
    if(-1 == setsockopt(cli_fd, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keep_interval, sizeof(keep_interval)))
    {
      perror("TCP_KEEPINTVL error");
      break;
    }
    if(-1 == setsockopt(cli_fd, IPPROTO_TCP, TCP_KEEPCNT, (void *)&keep_count, sizeof(keep_count)))
    {
      perror("TCP_KEEPCNT error");
      break;
    }
    printf("%s|%s|%d: Accept a connection from %s:%d\n", __FILE__, __func__, __LINE__, inet_ntoa(client.sin_addr), ntohs(client.sin_port));
    if (cli_fd == -1)
    {
      perror("accept");
      continue;
    }
    while (1)
    {
      memset(buffer, 0, sizeof(buffer));
      nread = recv(cli_fd, buffer, sizeof(buffer), 0);
      printf("%s|%s|%d:nread=%d, buffer=%s\n", __FILE__, __func__, __LINE__, nread, buffer);
      if (nread > 0)
      {
        if (strstr(buffer, "open"))
        {
          pthread_mutex_lock(&key_1);
          pthread_cond_signal(&cond_1);
          pthread_mutex_unlock(&key_1);
        }
      }
      else if (0 == nread || -1 == nread)
      {
        break;
      }
    }
    close(cli_fd);
  }
  pthread_exit(0);
}

int main(int argc, char **argv)
{
  int ret;
  pthread_t aly_rec;
  pthread_t su_rec;
  pthread_t sock_rec;
  toysort_init();

  if (false == (ret = judge_exist("mjpg_streamer")))
  {
    printf("mjpg_streamer is not exist!\n");
    goto END;
  }

  if (wiringPiSetup() == -1)
  {
    printf("wiringPi init false!\n");
    goto END;
  }
  if ((fd = serialOpen("/dev/ttyS5", 115200)) < 0)
  {
    fprintf(stderr, "Unable to open serial device: %s\n", strerror(errno));
    goto END;
  }

  pthread_create(&aly_rec, NULL, alycat, NULL);
  pthread_create(&su_rec, NULL, sucat, NULL);
  pthread_create(&sock_rec, NULL, sockcat, NULL);

  pthread_join(aly_rec, NULL);
  pthread_join(su_rec, NULL);
  pthread_join(sock_rec, NULL);

  pthread_mutex_destroy(&key_1);
  pthread_cond_destroy(&cond_1);
  close(fd);
END:
  toysort_fin();
  return 0;
}
